﻿using System;
using System.IO;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace TinyAsset
{
    public class BundledAssetLoader : AssetLoader
    {
        AssetBundleLoader assetBundleLoader;

        AssetBundleRequest assetBundleRequest;

        public BundledAssetLoader(string assetPath, string assetName, System.Type assetType, AssetBundleLoader loader)
            : base(assetPath, assetName, assetType)
        {
            assetBundleLoader = loader;
        }

        public BundledAssetLoader(string assetPath, string assetName, bool additive, int stack, AssetBundleLoader loader)
            : base(assetPath + stack, assetName, additive)
        {
            assetBundleLoader = loader;
        }

        public override UnityEngine.Object asset { get; protected set; }

        public override Scene scene { get; protected set; }

        protected override AsyncOperation asyncSceneOperation { get; set; }

        protected override void AsyncAssetLoadHandler(string assetName, Type assetType)
        {
            if (!assetBundleLoader.IsDone)
            {
                Progress = assetBundleLoader.Progress * 0.5f;
                return;
            }

            if (assetBundleRequest == null && assetBundleLoader.assetBundle != null)
                assetBundleRequest = assetBundleLoader.assetBundle.LoadAssetAsync(assetName, assetType);

            if (assetBundleRequest == null)
            {
                IsCompleted = true;
                return;
            }

            Progress = (assetBundleLoader.Progress + assetBundleRequest.progress) * 0.5f;
            IsCompleted = assetBundleRequest.isDone;

            if (IsCompleted)
            {
                asset = assetBundleRequest.asset;
                assetBundleRequest = null;
            }
        }

        protected override void AsyncSceneLoadHandler(string assetName, LoadSceneParameters parameters)
        {
            if (!assetBundleLoader.IsDone)
            {
                Progress = assetBundleLoader.Progress * 0.5f;
                return;
            }

            if (asyncSceneOperation == null && assetBundleLoader.assetBundle != null)
            {
                string sceneName = Path.GetFileNameWithoutExtension(assetName);
                bool _allowSceneActivation = allowSceneActivation;
                asyncSceneOperation = SceneManager.LoadSceneAsync(sceneName, parameters);
                if (asyncSceneOperation != null)
                    asyncSceneOperation.allowSceneActivation = _allowSceneActivation;
            }

            if (asyncSceneOperation == null)
            {
                IsCompleted = true;
                return;
            }

            Progress = (assetBundleLoader.Progress + asyncSceneOperation.progress) * 0.5f;
            IsCompleted = asyncSceneOperation.isDone || (asyncSceneOperation.allowSceneActivation == false && asyncSceneOperation.progress == 0.9f);

            if (IsCompleted)
            {
                scene = SceneManager.GetSceneAt(SceneManager.sceneCount - 1);
                asyncSceneOperation = null;
            }
        }

        protected override void SyncAssetLoadHandler(string assetName, Type assetType)
        {
            if(assetBundleLoader.assetBundle != null)
                asset = assetBundleLoader.assetBundle.LoadAsset(assetName, assetType);
            IsCompleted = true;
        }

        protected override void SyncSceneLoadHandler(string assetName, LoadSceneParameters parameters)
        {
            if(assetBundleLoader.assetBundle != null)
            {
                string sceneName = Path.GetFileNameWithoutExtension(assetName);
                scene = SceneManager.LoadScene(sceneName, parameters);
            }
            IsCompleted = true;
        }

        public string GetAssetBundleName()
        {
            return assetBundleLoader.Key;
        }
    }

}